package com.agentframework.examples.jinhua;

import com.agentframework.core.action.BeanOutputAbstractAction;
import com.agentframework.core.annotation.Action;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.UserMessage;

import java.util.List;
import java.util.Set;

import static com.agentframework.core.agent.Agent.ACTION;
import static com.agentframework.core.agent.Agent.SEND_TO;

/**
 * @author wangjun
 **/
@Action(name = "player_todo")
public class PlayerAction extends BeanOutputAbstractAction {

    List<String> actions = List.of("view_cards", "bet", "compare", "fold");

    String prompt = """
            请必须且只能返回如下JSON格式： \n
            {
                "playerId": "你自己的玩家ID",
                "message": "我是玩家（玩家ID）我要看牌",
                "action": "你需要选择当前轮次操作，看牌：view_cards, 下注：bet, 比牌：compare, 弃牌：fold"
            }
            
            例如：看牌  \n
            {
                "playerId": e9fc1d4d"",
                "message": "我是玩家e9fc1d4d，我要看牌",
                "action": "view_cards"
            }
            
            下注： \n
            
            {
                "playerId": e9fc1d4d"",
                "message": "我是玩家e9fc1d4d，我要下注50倍",
                "action": "bet"
            }
            
            比牌： \n
            {
                "playerId": e9fc1d4d"",
                "message": "我是玩家e9fc1d4d，我要跟玩家xxx比牌",
                "action": "compare"
            }
            
            弃牌： \n
            {
                "playerId": e9fc1d4d"",
                "message": "我是玩家e9fc1d4d，我选择弃牌",
                "action": "fold"
            }
             \n
            特别注意：
            如果是比牌，请在message中指定需要比牌的玩家，比如“我是玩家xxx，我要跟玩家xxx比牌”
            如果是下注，必须指定下注金额，比如“我是玩家e9fc1d4d，我要下注50倍”
            """;

    public PlayerAction() {
        super("player_todo");
    }

    @Override
    protected String getFormatInstruction() {
        return prompt;
    }

    @Override
    protected void doHandleResponseMessage(Message message, Object response) {
        var playerActionResp = (PlayerActionResp) response;

        String action = playerActionResp.action();

        if (!actions.contains(action)) {
            // 玩家没有指定对应的动作，需要提醒他再次做出决定
            Message reactionMessage = new UserMessage("请做出对应的动作决定 看牌：view_cards, 下注：bet, 比牌：compare, 弃牌：fold，即回复的json结构中必须指定action正确的值");
            reactionMessage.getMetadata().put(SEND_TO, Set.of(playerActionResp.playerId()));
            publishMessage(reactionMessage);
            return;
        }

        // 把玩家需要处理的动作告诉荷官，玩家不直接调用游戏工具
        Message playerActionMessage = new UserMessage(playerActionResp.message());
        playerActionMessage.getMetadata().put(ACTION, action);
        playerActionMessage.getMetadata().put(SEND_TO, Set.of(getDealerAgentId()));
        publishMessage(playerActionMessage);

    }

    @Override
    protected Class<?> getResponseType() {
        return PlayerActionResp.class;
    }

    private String getDealerAgentId() {
        return ((JinhuaEnvironment) getAgent().getEnvironment()).getJinhuaGameState().getDealerAgent().getAgentId();
    }

    record PlayerActionResp(String playerId, String message, String action) {

    }

}
